﻿using System;
using System.Collections.Generic;
using System.Data;
using Util.Database;

namespace AutoNZBLoader
{
    public class Request
    {
        private readonly string _Name;
        public string Name
        {
            get { return _Name; }
        }

        private readonly uint _ShowID;
        public uint ShowID
        {
            get { return _ShowID; }
        }

        private readonly uint _Season;
        public uint Season
        {
            get { return _Season; }
        }

        private readonly uint _Episode;
        public uint Episode
        {
            get { return _Episode; }
        }

        private readonly string _NameQuery;
        public string NameQuery
        {
            get { return _NameQuery; }
        }

        private readonly string _DetailsQuery;
        public string DetailsQuery
        {
            get { return _DetailsQuery; }
        } 


        private Request(string Name, uint ShowID, uint Season, uint Episode, string NameQuery, string DetailsQuery)
        {
            this._Name = Name;
            this._ShowID = ShowID;
            this._Season = Season;
            this._Episode = Episode;
            this._NameQuery = NameQuery;
            this._DetailsQuery = DetailsQuery;
        }

        public void MarkAsDownloaded(uint season, uint episode, string downloadAddress)
        {
            using (System.Data.IDbCommand cmd = DB.CreateCommand())
            {
                cmd.CommandText = "insert into downloaded(id_show, season, episode, downloaddate, downloadaddress) values(?, ?, ?, datetime(), ?)";
                IDbDataParameter par = cmd.CreateParameter();
                par.Value = ShowID;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = season;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = episode;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = downloadAddress;
                cmd.Parameters.Add(par);
                cmd.ExecuteNonQuery();

                if (this.Season != 0 && this.Episode != 0)
                {
                    cmd.Parameters.Clear();
                    cmd.CommandText = "delete from request where id_show=? and season=? and episode=?";
                    par = cmd.CreateParameter();
                    par.Value = ShowID;
                    cmd.Parameters.Add(par);
                    par = cmd.CreateParameter();
                    par.Value = this.Season;
                    cmd.Parameters.Add(par);
                    par = cmd.CreateParameter();
                    par.Value = this.Episode;
                    cmd.Parameters.Add(par);
                    cmd.ExecuteNonQuery();
                }
            }
        }

        public bool IsAlreadyDownloaded(uint season, uint episode)
        {
            using (System.Data.IDbCommand cmd = DB.CreateCommand())
            {
                cmd.CommandText = "select count(*) from downloaded where id_show=? and season=? and episode=?";
                IDbDataParameter par = cmd.CreateParameter();
                par.Value = ShowID;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = season;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = episode;
                cmd.Parameters.Add(par);
                return ((long)cmd.ExecuteScalar()) != 0;
            }
        }

        public bool Matches(FeedItem feedItem)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder(feedItem.Title);
            for (int n = 0; n < sb.Length; ++n)
            {
                if (!char.IsLetterOrDigit(sb[n]))
                {
                    sb[n] = ' ';
                }
            }
            string title = sb.ToString();

            string NameStr, DetailsStr;
            uint S, E;
            try
            {
                Util.TitleParser.TitleParser.ParseTitle(title, out NameStr, out DetailsStr, out S, out E);

                if ((feedItem.Episode == Episode || Episode == 0) && (feedItem.Season == Season || Season == 0))
                {
                    if (MatchQuery(NameQuery, NameStr) && MatchQuery(DetailsQuery, DetailsStr))
                    {
                        return true;
                    }
                }
            }
            catch (Exception)
            {
            }

            return false;
        }

        private static bool MatchQuery(string qry, string str)
        {
            if (qry.Trim().Length == 0)
            {
                return true;
            }

            Util.QueryParser.Token.IToken t = Util.QueryParser.Parser.BuildTokenTree(qry);
            return t.Evaluate(str);
        }

        private static IList<Request> _Requests;
        public static IList<Request> Requests
        {
            get
            {
                if (_Requests == null)
                {
                    List<Request> lst = new List<Request>();

                    using (System.Data.IDbCommand cmd = DB.CreateCommand())
                    {
                        cmd.CommandText = "select * from request, show where show.id = request.id_show";
                        using (IDataReader dr = cmd.ExecuteReader())
                        {
                            uint season, episode;
                            while (dr.Read())
                            {
                                try
                                {
                                    season = (uint)(long)dr["SEASON"];
                                }
                                catch (Exception)
                                {
                                    season = 0;
                                }
                                try
                                {
                                    episode = (uint)(long)dr["EPISODE"];
                                }
                                catch (Exception)
                                {
                                    episode = 0;
                                }

                                lst.Add(new Request(dr["SHOWNAME"].ToString(), (uint)(long)dr["ID_SHOW"], season, episode, dr["NAMEQUERY"].ToString(), dr["DETAILSQUERY"].ToString()));
                            }
                        }
                    }
                    _Requests = new System.Collections.ObjectModel.ReadOnlyCollection<Request>(lst);
                }
                return _Requests;
            }
        }
    }
}
